/*
 * @Author: Du Weixing duweixing@sgsimulation.com
 * @Date: 2024-09-09 18:47:17
 * @LastEditors: Du Weixing duweixing@sgsimulation.com
 * @LastEditTime: 2024-12-06 22:05:14
 * @FilePath: \SGFEM\Solver\SectionCalculator\BeamSection\SectionParser\test\BeamSectionParserTest.hpp
 * @Description: 
 * 
 * Copyright (c) 2024 by 神工仿真, All Rights Reserved. 
 */

#pragma once
#include "gtest/gtest.h"
#include "DBManager/Database/DatabaseFactory.h"
#include "DBManager/DBServiceFactory.h"
#include "DBManager/IService/Input/Material/IIsotropicMaterialService.h"
// #include "DBManager/IService/Input/Property/IPBEAMLService.h"
#include "DBManager/IService/Input/Property/IPBEAMService.h"
#include "DataStructure/Input/Property/BeamSectionStandardTypes.h"
#include "../BeamSectionParser.h"

using SG::DataStructure::Common::Id;
using SG::DataStructure::FEM::IsotropicMaterial;
using SG::DataStructure::FEM::BeamSectionStandardTypes;
// using SG::DataStructure::FEM::PBEAMLData;
using SG::DataStructure::FEM::PBEAMData;
using SG::FEMSolver::Element::BeamSectionParser;
using namespace SG::DBManager;

extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;
class BeamSectionParserTest : public ::testing::Test
{
public:
    static void SetUpTestSuite ()
    {
        DB_SERVICEFACTORY->ClearDatabase ();

        // 梁属性1, id为1，直接指定属性数值
        PBEAMData pBeam;
        pBeam.m_id     = 2;
        pBeam.m_mId    = 2;
        pBeam.m_nsges  = 1;
        pBeam.m_ccf    = 1;
        pBeam.m_cweld  = 0;
        pBeam.m_SO[0]  = 0.0;
        pBeam.m_XXB[0] = 0.0;
        pBeam.m_A[0]   = 7.0;
        pBeam.m_I1[0]  = 7.145833;
        pBeam.m_I2[0]  = 2.333333;
        pBeam.m_I12[0] = 0.4;
        pBeam.m_J[0]   = 6.003188;
        pBeam.m_NSM[0] = 2.0;
        pBeam.m_C1[0]  = 1.75;
        pBeam.m_C2[0]  = 1.0;
        pBeam.m_D1[0]  = -1.75;
        pBeam.m_D2[0]  = 1.0;
        pBeam.m_E1[0]  = -1.75;
        pBeam.m_E2[0]  = -1.0;
        pBeam.m_F1[0]  = 1.75;
        pBeam.m_F2[0]  = -1.0;
        pBeam.m_K1     = 0.8;
        pBeam.m_K2     = 0.7;
        pBeam.m_S1     = 0.0;
        pBeam.m_S2     = 0.0;
        pBeam.m_NSIA   = 1.0;
        pBeam.m_NSIB   = 2.0;
        pBeam.m_CWA    = 0.3;
        pBeam.m_CWB    = 0.6;
        pBeam.m_M1A    = 1.0;
        pBeam.m_M2A    = 2.0;
        pBeam.m_M1B    = 2.0;
        pBeam.m_M2B    = 1.0;
        pBeam.m_N1A    = 0.5;
        pBeam.m_N2A    = 0.8;
        pBeam.m_N1B    = 0.5;
        pBeam.m_N2B    = 0.8;
        DB_SERVICEFACTORY->get<IPBEAMService> ()->Add (pBeam);

        // 梁属性2，id为2，使用标准形状指定属性
        // PBEAMLData pBeamL;
        // pBeamL.m_id  = 2;
        // pBeamL.m_mId = 1;
        // pBeamL.SetBeamSectionStandardTypes (BeamSectionStandardTypes::BEAMSECTYPE_BOX);
        // pBeamL.m_dimension = {4.0, 5.0, 2.0, 1.0};
        // pBeamL.m_nsm       = 0.0;
        // dbServiceFactory->get<IPBEAMLService> ()->Add (pBeamL);

        // 材料1，id为1
        IsotropicMaterial material;
        material.m_id  = 2;
        material.m_E   = 70000.0;
        material.m_nu  = 0.3;
        material.m_rho = 2.7e-9;
        DB_SERVICEFACTORY->get<IIsotropicMaterialService> ()->Add (material);
    }
};

// 测试获取直接指定数值的梁属性
TEST_F (BeamSectionParserTest, GetSectionProperty)
{
    // Test data
    BeamSectionParser parser;
    Id                pId = 2;
    PBEAMData         propertyTest;
    parser.GetSectionProperty (DB_SERVICEFACTORY, pId, _OUT propertyTest);
    IsotropicMaterial materialTest;
    parser.GetMatrial (propertyTest.m_mId, _OUT materialTest);

    // Target data (property)
    PBEAMData propertyTarget;
    propertyTarget.m_id     = 2;
    propertyTarget.m_mId    = 2;
    propertyTarget.m_nsges  = 1;
    propertyTarget.m_ccf    = 1;
    propertyTarget.m_cweld  = 0;
    propertyTarget.m_SO[0]  = 0.0;
    propertyTarget.m_XXB[0] = 0.0;
    propertyTarget.m_A[0]   = 7.0;
    propertyTarget.m_I1[0]  = 7.145833;
    propertyTarget.m_I2[0]  = 2.333333;
    propertyTarget.m_I12[0] = 0.4;
    propertyTarget.m_J[0]   = 6.003188;
    propertyTarget.m_NSM[0] = 2.0;
    propertyTarget.m_C1[0]  = 1.75;
    propertyTarget.m_C2[0]  = 1.0;
    propertyTarget.m_D1[0]  = -1.75;
    propertyTarget.m_D2[0]  = 1.0;
    propertyTarget.m_E1[0]  = -1.75;
    propertyTarget.m_E2[0]  = -1.0;
    propertyTarget.m_F1[0]  = 1.75;
    propertyTarget.m_F2[0]  = -1.0;
    propertyTarget.m_K1     = 0.8;
    propertyTarget.m_K2     = 0.7;
    propertyTarget.m_S1     = 0.0;
    propertyTarget.m_S2     = 0.0;
    propertyTarget.m_NSIA   = 1.0;
    propertyTarget.m_NSIB   = 2.0;
    propertyTarget.m_CWA    = 0.3;
    propertyTarget.m_CWB    = 0.6;
    propertyTarget.m_M1A    = 1.0;
    propertyTarget.m_M2A    = 2.0;
    propertyTarget.m_M1B    = 2.0;
    propertyTarget.m_M2B    = 1.0;
    propertyTarget.m_N1A    = 0.5;
    propertyTarget.m_N2A    = 0.8;
    propertyTarget.m_N1B    = 0.5;
    propertyTarget.m_N2B    = 0.8;

    // Check property
    ASSERT_TRUE (propertyTarget == propertyTest);

    // Target data (material)
    IsotropicMaterial materialTarget;
    materialTarget.m_E   = 70000.0;
    materialTarget.m_nu  = 0.3;
    materialTarget.m_rho = 2.7e-9;

    // Check
    ASSERT_TRUE (materialTarget == materialTest);
}

// 测试获取使用标准形状指定的梁属性
// TEST_F (BeamSectionParserTest, GetStandardSectionProperty)
// {
//     // Test data
//     BeamSectionParser parser;
//     Id                pId = 2;
//     PBEAMData         propertyTest;
//     parser.GetSectionProperty (dbServiceFactory, pId, _OUT propertyTest);

//     // Target data
//     PBEAMData propertyTarget;
//     propertyTarget.m_id  = 2;
//     propertyTarget.m_mId = 1;
//     propertyTarget.m_A   = 18.0;
//     // propertyTarget.m_yS = 0.0;
//     // propertyTarget.m_zS = 0.0;
//     // propertyTarget.m_yC = 0.0;
//     // propertyTarget.m_zC = 0.0;
//     propertyTarget.m_I1  = 41.5;
//     propertyTarget.m_I2  = 26.0;
//     propertyTarget.m_I12 = 0.0;
//     propertyTarget.m_J   = 36.0;
//     propertyTarget.m_K1  = 0.1111111;
//     propertyTarget.m_K2  = 0.4444444;
//     propertyTarget.m_NSM = 0.0;
//     propertyTarget.SetStressPoints ({2.5, 2.0, -2.5, 2.0, -2.5, -2.0, 2.5, -2.0});

//     // Check property
//     ASSERT_TRUE (propertyTarget == propertyTest);
// }
